<template>
  <v-page
    ref="pageRef"
    :background="dynamicContent?.backgroundColor ?? '#f5f6fa'"
    :scroll-top="scrollTop"
    :scroll-into-view="scrollIntoView"
    :scroll-with-animation="false"
    @scroll="scrollHandle"
  >
    <template v-if="!toLandingPage && !loading" #header>
      <v-navbar home :title="title" />
    </template>
    <template v-if="!toLandingPage && !loading" #default>
      <view v-if="dynamicContent?.backgroundImage" class="page-background">
        <v-image
          width="100vw"
          mode="widthFix"
          :src="dynamicContent?.backgroundImage"
        />
      </view>
      <template v-if="landingPageData">
        <landing-page-carousel
          v-if="components?.carousel"
          :landing-page-data="landingPageData"
          :component="components.carousel"
        />
        <template v-for="(item, index) in components?.list" :key="index">
          <view v-if="isShowGap(index)" class="gap" />
          <landing-page-swiper
            v-if="item.el === 'Swiper'"
            :landing-page-data="landingPageData"
            :component="item"
          />
          <landing-page-sales
            v-if="item.el === 'Goods' && product"
            :product="product"
            :landing-page-data="landingPageData"
            :component="item"
            :discount-price="discount.amount"
            @show-guarantee="isShowGuarantee = true"
            @to-spec="toTheSpec"
          />
          <landing-page-group-purchase
            v-if="item.el === 'CanTuan'"
            :landing-page-data="landingPageData"
            :component="item"
            @click-purchase="toTheSpec"
          />
          <landing-page-merchant
            v-if="item.el === 'Merchant'"
            :landing-page-data="landingPageData"
            :component="item"
          />
          <landing-page-title
            v-if="item.el === 'Title'"
            :landing-page-data="landingPageData"
            :component="item"
          />
          <landing-page-text
            v-if="item.el === 'Text'"
            :landing-page-data="landingPageData"
            :component="item"
          />
          <landing-page-comment-group
            v-if="item.el === 'CommentGroup'"
            :landing-page-data="landingPageData"
            :component="item"
          />
          <template v-if="item.el === 'Image'">
            <v-image
              v-for="(image, imageIndex) in item.imageList"
              :key="imageIndex"
              :src="image.url"
              width="100vw"
              :lazy-load="false"
              mode="widthFix"
            />
          </template>
          <view v-if="item.el === 'Detail'" class="product-details">
            <view class="product-details-header">
              <view class="left-line" />
              <view class="header-text">
                {{ item.title }}
              </view>
              <view class="right-line" />
            </view>
            <v-image
              v-for="(image, imageIndex) in item.imageList"
              :key="imageIndex"
              :src="image.url"
              width="100vw"
              mode="widthFix"
              :lazy-load="false"
            />
          </view>
          <template v-if="item.el === 'Spec' && product">
            <template v-if="discount.amount">
              <view class="coupon-container" @click="toTheSpec">
                <v-image
                  height="200rpx"
                  width="100vw"
                  oss-src="landing-page-coupon.png"
                />
                <view class="coupon-content">
                  <text class="coupon-label">
                    现在下单，立享
                  </text>
                  <text class="coupon-text">
                    {{ `${discount.amount}元` }}
                  </text>
                </view>
              </view>
              <view class="gap" />
            </template>
            <view id="spec">
              <landing-page-select
                v-if="components?.goods"
                :product="product"
                :landing-page-data="landingPageData"
                :component="components.goods"
                :discount-price="discount.amount"
                :discount-type="discount.type"
                :query-data="queryData"
                @show-popper="isShowRemarkPopper = true"
                @hide-popper="isShowRemarkPopper = false"
              />
            </view>
          </template>
        </template>
      </template>
    </template>
    <template v-else #default>
      <view :style="{ height: `${navBarHeight + statusBarHeight}px` }" />
      <view
        class="skeleton image"
        :style="{ height: '94vw', width: '94vw', margin: '0 3vw' }"
      />
      <view class="skeleton-block">
        <view class="skeleton text" />
        <view class="skeleton text" />
        <view class="skeleton text" />
      </view>
      <view
        class="skeleton image"
        :style="{ height: '150rpx', width: '94vw', margin: '0 3vw' }"
      />
      <view class="skeleton-block">
        <view class="skeleton text" />
        <view class="skeleton text" />
        <view class="skeleton text" />
      </view>
      <view
        class="skeleton image"
        :style="{ height: '150rpx', width: '94vw', margin: '0 3vw' }"
      />
      <view class="skeleton-block">
        <view class="skeleton text" />
        <view class="skeleton text" />
        <view class="skeleton text" />
      </view>
    </template>
    <template v-if="!toLandingPage" #popup>
      <landing-page-buy-button
        v-if="showToBottom && pageHeight && landingPageData && components?.buy"
        :landing-page-data="landingPageData"
        :component="components.buy"
        @click="toTheSpec"
      />
      <movable-area
        class="floating-button-container"
        :style="{
          '--top': `${navBarHeight + statusBarHeight}px`
        }"
      >
        <movable-view
          v-if="pageHeight && !isShowRemarkPopper"
          :x="buttonListX"
          :y="buttonListY"
          direction="all"
          class="floating-button-list"
          :style="{ height: buttonListHeight }"
        >
          <view
            v-if="showToTop"
            class="floating-button top-icon"
            @click="toTheTop"
          >
            <v-icon size="40rpx" src="@/static/icons/to-the-top.svg" />
            <view>置顶</view>
          </view>
          <view
            v-if="dynamicContent?.customer && merchantContact"
            class="floating-button service-icon"
          >
            <v-icon size="40rpx" src="/static/icons/service-icon-white.svg" />
            <view>客服</view>
            <view class="service-icon-blank">
              <contact-button
                :tnt-inst-id="merchantContact.tntInstId"
                :scene="merchantContact.scene"
                size="90rpx"
                icon="/static/icons/service-blank.svg"
              />
            </view>
          </view>
        </movable-view>
      </movable-area>
      <landing-page-guarantee-popup
        v-if="landingPageData && components?.goods"
        v-model:show="isShowGuarantee"
        :landing-page-data="landingPageData"
        :component="components.goods"
      />
      <landing-page-popup ref="popupRef" @to-spec="toTheSpec" />
    </template>
  </v-page>
</template>

<script setup lang="ts">
import usePageRecord from '@/composables/use-page-record';
import LandingPageCarousel from './modules/landing-page-carousel.vue';
import LandingPageSwiper from './modules/landing-page-swiper.vue';
import LandingPageSales from './modules/landing-page-sales.vue';
import LandingPageMerchant from './modules/landing-page-merchant.vue';
import LandingPageGuaranteePopup from './modules/landing-page-guarantee-popup.vue';
import LandingPageSelect from './modules/landing-page-select.vue';
import LandingPageGroupPurchase from './modules/landing-page-group-purchase.vue';
import LandingPageTitle from './modules/landing-page-title.vue';
import LandingPageText from './modules/landing-page-text.vue';
import LandingPageBuyButton from './modules/landing-page-buy-button.vue';
import LandingPagePopup from './modules/landing-page-popup.vue';
import LandingPageCommentGroup from './modules/landing-page-comment-group.vue';
import useNavbarLayout from '@/composables/use-navbar-layout';
import type VPage from '@/components/v-page/v-page.vue';

const { navBarHeight, statusBarHeight } = useNavbarLayout();
const loading = ref(true);

const popupRef = ref<InstanceType<typeof LandingPagePopup>>();
const isShowRemarkPopper = ref(false);
const isShowGuarantee = ref(false);

const landingStore = $store.landing();
const landingPageData = computed(() => landingStore.landingPageData);
const dynamicContent = computed(() => landingStore.dynamicContent);
const product = computed(() => landingStore.product);
const discount = computed(() => landingStore.discount);
const components = computed(() => landingStore.components);
const merchantContact = computed(() => landingStore.merchantContact);
const queryData = computed(() => landingStore.queryData);

const title = computed(() => {
  if (!landingPageData.value) return '';
  return landingPageData.value?.page_title || '商品详情';
});

const isShowGap = (index: number) => {
  const current = landingStore.components?.list[index];
  const last = landingStore.components?.list[index - 1];
  if (current?.el === 'Swiper') return false;
  if (last?.el === 'Swiper') return false;
  return true;
};

const pageRef = ref() as Ref<InstanceType<typeof VPage>>;
const pageHeight = ref(0);
const showBuyButton = ref(false);
onMounted(async () => {
  pageHeight.value = await pageRef.value.getPageHeight(pageRef.value);
  setTimeout(() => {
    showBuyButton.value = true;
  }, 500);
});

let currentScrollTop = 0;
const scrollTop = ref<number>();
const showToTop = ref(false);
const scrollIntoView = ref('');
const showToBottom = ref(true);
let updateTimer: number;
const updateShowToBottom = async () => {
  clearTimeout(updateTimer);
  updateTimer = setTimeout(() => {
    const query = uni.createSelectorQuery();
    query
      .select('#spec')
      .boundingClientRect((res) => {
        const result = res as UniApp.NodeInfo;
        if (!result) return;
        const top = result.top as number;
        const bottom = result.bottom as number;
        const height = result.height as number;
        const header = navBarHeight.value + statusBarHeight.value;
        showToBottom.value =
          top + header - 20 > height || bottom + header + 20 < height;
      })
      .exec();
  }, 100);
};

const scrollHandle = (e: ScrollEvent) => {
  currentScrollTop = e.detail.scrollTop;
  showToTop.value = currentScrollTop > 100;
  updateShowToBottom();
};
const toTheTop = async () => {
  scrollTop.value = 0;
  await new Promise((resolve) => setTimeout(resolve, 100));
  scrollTop.value = undefined;
};
const toTheSpec = async () => {
  landingStore.toSpec = false;
  scrollIntoView.value = 'spec';
  showToBottom.value = false;
  await new Promise((resolve) => setTimeout(resolve, 100));
  scrollIntoView.value = '';
};

const buttonListX = computed(() => uni.upx2px(750 - 102));
const buttonListY = computed(() => pageHeight.value - uni.upx2px(400));
const buttonListHeight = computed(() =>
  merchantContact.value ? '200rpx' : '90rpx'
);

const toLandingPage = ref(false);
onLoad((query) => {
  landingStore.initData();
  uni.showLoading({ mask: true });
  landingStore.queryData = query ?? {};
  landingStore.landingPageId = query?.id;
  landingStore.pageId = query?.pageId;
  landingStore.navigatedMerchantIndex = false;
  usePageRecord(query);
});
onShow(async () => {
  landingStore.isShowPopup = true;
  await landingStore.loadData();
  if (!landingStore.landingPageData || !landingStore.product) {
    uni.hideLoading();
    uni.reLaunch({ url: '/pages/index/index' });
    return;
  }
  uni.hideLoading();
  toLandingPage.value =
    landingStore.refluxList.length > 1 ||
    !!landingStore.merchant?.store_decoration_index_flag;
  landingStore.refluxIndex += 1;
  await nextTick();
  if (toLandingPage.value) {
    if (landingStore.refluxCurrent) {
      if (landingStore.refluxCurrent.type === 'MARKETING_PAGE_DISCOUNT') {
        uni.navigateTo({ url: '/pages/landing-page/landing-page-marketing' });
      } else {
        uni.navigateTo({ url: '/pages/landing-page/landing-page' });
      }
    } else if (
      !!landingStore.merchant?.store_decoration_index_flag &&
      !landingStore.navigatedMerchantIndex
    ) {
      const merchantId = landingStore.landingPageData.merchant_id;
      uni.navigateTo({
        url: `/pages/store/store-page?merchant=${merchantId}`
      });
      landingStore.navigatedMerchantIndex = true;
    } else {
      uni.reLaunch({ url: '/pages/index/index' });
    }
  } else {
    loading.value = false;
    popupRef.value?.checkPopup();
  }
});
</script>

<style lang="scss" scoped>
.page-background {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: fit-content;
}

.product-details {
  .product-details-header {
    height: 93rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    .left-line {
      height: 50rpx;
      height: 1px;
      background: linear-gradient(to right, transparent, #666);
    }
    .header-text {
      font-size: 32rpx;
      font-weight: bold;
    }
    .right-line {
      height: 50rpx;
      height: 1px;
      background: linear-gradient(to left, transparent, #666);
    }
  }
}

.coupon-container {
  position: relative;
  margin-top: -40rpx;
  height: fit-content;
  width: 100vw;
  .coupon-content {
    position: absolute;
    top: 55rpx;
    left: 30rpx;
    font-size: 40rpx;
    line-height: 60rpx;
    .coupon-label {
      color: white;
    }
    .coupon-text {
      color: #fded8f;
    }
  }
}

.floating-button-container {
  position: fixed;
  top: var(--top);
  left: 0;
  width: 100vw;
  height: calc(100vh - var(--top) - constant(safe-area-inset-bottom));
  height: calc(100vh - var(--top) - env(safe-area-inset-bottom));
  pointer-events: none;
}
.floating-button-list {
  width: 90rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 20rpx;
  margin-bottom: constant(safe-area-inset-bottom);
  margin-bottom: env(safe-area-inset-bottom);
  .floating-button {
    position: relative;
    height: 90rpx;
    width: 90rpx;
    border-radius: 50%;
    box-shadow: 0px 2px 4px 0px #2c070a17;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    font-size: 20rpx;
    padding-bottom: 10rpx;
    box-sizing: border-box;
    pointer-events: all;
    .service-icon-blank {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
    }
  }
  .floating-button.top-icon {
    background-color: white;
  }
  .floating-button.service-icon {
    color: white;
    background: linear-gradient(161.57deg, #ff6f6f 28.44%, #ff2f3b 75.31%);
  }
}
.gap {
  height: 24rpx;
  width: 100%;
}

.skeleton {
  border-radius: 12rpx;
  background-color: #eee;
  animation: blink 1.5s infinite ease-in-out;
  &.text {
    height: 50rpx;
  }
}

.skeleton-block {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 24rpx;
  padding: 24rpx;
  background-color: white;
  border-radius: 16rpx;
  margin: 24rpx;
}

@keyframes blink {
  0% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
  100% {
    opacity: 1;
  }
}
</style>
